package com.braincookie.plugins.jira.tabpanels;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.LoggerFactory;

import com.atlassian.extras.common.log.Logger;
import com.atlassian.jira.bc.issue.search.SearchService;
import com.atlassian.jira.config.ConstantsManager;
import com.atlassian.jira.config.properties.ApplicationProperties;
import com.atlassian.jira.issue.search.SearchException;
import com.atlassian.jira.project.browse.BrowseContext;
import com.atlassian.query.Query;
import com.atlassian.sal.api.pluginsettings.PluginSettings;
import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
import com.braincookie.plugins.jira.tabpanels.fragments.FilterTabPanelFragment;
import com.braincookie.plugins.jira.tabpanels.fragments.FilterUnresolvedIssuesByCustomFragment;
import com.braincookie.plugins.jira.tabpanels.fragments.FilterUnresolvedIssuesByPriorityFragment;
import com.atlassian.jira.plugin.projectpanel.ProjectTabPanel;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.template.VelocityTemplatingEngine;
import com.atlassian.jira.util.VelocityParamFactory;
import com.atlassian.jira.util.velocity.VelocityRequestContextFactory;
import com.atlassian.jira.web.FieldVisibilityManager;


public class FilterTabPanel extends AbstractFragmentBasedFilterProjectTabPanel implements ProjectTabPanel
{
    private final VelocityTemplatingEngine velocityEngine;
    private final VelocityParamFactory paramFactory;
    private final ApplicationProperties properties;
    private final JiraAuthenticationContext authenticationContext;
    private final FieldVisibilityManager visManager;
    private final ConstantsManager constantsManager;
    final VelocityRequestContextFactory reqContextFactory;
	private final SearchService searchService;
	private final PluginSettingsFactory settingsFactory;
    public FilterTabPanel(final VelocityTemplatingEngine velocityEngine, 
    					  final VelocityParamFactory paramFactory, 
    					  final ApplicationProperties properties, 
    					  final JiraAuthenticationContext authenticationContext, 
    					  final FieldVisibilityManager visManager, 
    					  final ConstantsManager constantsManager, 
    					  final VelocityRequestContextFactory reqContextFactory,
    					  final SearchService searchService,
    					  final PluginSettingsFactory settingsFactory) {
//    	this.unresolvedIssuesByPriorityFragment = new FilterUnresolvedIssuesByPriorityFragment(velocityEngine, paramFactory, properties, authenticationContext, visManager, constantsManager, reqContextFactory, searchService);
 //   	this.unresolvedIssuesByCriticalityFragment = new FilterUnresolvedIssuesByCustomFragment(velocityEngine, paramFactory, properties, authenticationContext, visManager, constantsManager, reqContextFactory, searchService, "By Criticality", "customfield_10000");
 //   	this.unresolvedIssuesByProgramFragment = new FilterUnresolvedIssuesByCustomFragment(velocityEngine, paramFactory, properties, authenticationContext, visManager, constantsManager, reqContextFactory, searchService, "By Program", "customfield_10001");
    	this.velocityEngine = velocityEngine;
    	this.paramFactory = paramFactory;
    	this.properties = properties;
    	this.authenticationContext = authenticationContext;
    	this.visManager = visManager;
    	this.constantsManager = constantsManager;
    	this.reqContextFactory = reqContextFactory;
    	this.searchService = searchService;
    	this.settingsFactory = settingsFactory;    	
    }

    @Override
    protected List<FilterTabPanelFragment> getTopFragments(BrowseContext ctx)
    {
        return Collections.emptyList();
    }

    @Override
    protected List<FilterTabPanelFragment> getLeftColumnFragments(BrowseContext ctx)
    {
    	PluginSettings settings = settingsFactory.createSettingsForKey(ctx.getProject().getKey());
    	Map<String,String> leftFragments = (Map<String,String>) settings.get("LeftFragments");
    	
    	if (leftFragments == null) {
    		leftFragments = new HashMap<String,String>();
    		leftFragments.put("Priority",  "Priority");
    		settings.put("LeftFragments", leftFragments);
    	}
    	
        final List<FilterTabPanelFragment> frags = new ArrayList<FilterTabPanelFragment>();

        if (doesProjectHaveIssues(ctx))
        {
        	for (Map.Entry<String, String> entry : leftFragments.entrySet())
        	{
        		if (entry.getKey().equalsIgnoreCase("Priority")) {
        			frags.add(new FilterUnresolvedIssuesByPriorityFragment(velocityEngine, paramFactory, properties, authenticationContext, visManager, constantsManager, reqContextFactory, searchService));
        		} else {
        			frags.add(new FilterUnresolvedIssuesByCustomFragment(velocityEngine, paramFactory, properties, authenticationContext, visManager, constantsManager, reqContextFactory, searchService, entry.getValue(), entry.getKey()));
        		}
        	}
        }
        else
        {
//            frags.add(noIssuesFragment);
        }

        return frags;
    }
    
    @Override
    protected List<FilterTabPanelFragment> getRightColumnFragments(BrowseContext ctx)
    {
    	PluginSettings settings = settingsFactory.createSettingsForKey(ctx.getProject().getKey());
    	Map<String,String> rightFragments = (Map<String,String>) settings.get("RightFragments");
    	
    	if (rightFragments == null) {
    		rightFragments = new HashMap<String,String>();
    		rightFragments.put("customfield_10000", "Criticality");
    		rightFragments.put("customfield_10001", "Program");
    		settings.put("RightFragments", rightFragments);
    	}

    	final List<FilterTabPanelFragment> frags = new ArrayList<FilterTabPanelFragment>();

        if (doesProjectHaveIssues(ctx))
        {
        	for (Map.Entry<String, String> entry : rightFragments.entrySet())
        	{
        		if (entry.getKey().equalsIgnoreCase("Priority")) {
        			frags.add(new FilterUnresolvedIssuesByPriorityFragment(velocityEngine, paramFactory, properties, authenticationContext, visManager, constantsManager, reqContextFactory, searchService));
        		} else {
        			frags.add(new FilterUnresolvedIssuesByCustomFragment(velocityEngine, paramFactory, properties, authenticationContext, visManager, constantsManager, reqContextFactory, searchService, entry.getValue(), entry.getKey()));
        		}
        	}
        }
        else
        {
//            frags.add(noIssuesFragment);
        }

        return frags;
    }
    
    @Override
    public boolean showPanel(BrowseContext ctx)
    {
        return true;
    }

    private boolean doesProjectHaveIssues(BrowseContext ctx)
    {
        final Query query = ctx.createQuery();
        try
        {
            final long count = searchService.searchCount(ctx.getUser(), query);
            return count > 0;
        }
        catch (SearchException e)
        {
            // We can't assume that there are no issues
            return true;
        }
    }

}

